package com.tvunetworks.center.device.service.impl;

import com.fasterxml.jackson.databind.JsonNode;
import com.tvunetworks.center.common.exception.ClientException;
import com.tvunetworks.center.common.model.ps.PSR;
import com.tvunetworks.center.common.model.ps.PST;
import com.tvunetworks.center.common.util.MyUtil;
import com.tvunetworks.center.device.model.PtsPrs;
import com.tvunetworks.center.device.service.feign.GcsManageFeignService;
import com.tvunetworks.center.device.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.util.*;

/**
 * @program: tvucc-device
 * @description: 设备配对关系查询
 * @author lebronchen
 * @create: 2019-03-14 22:17
 **/
@Service
@Slf4j
public class DevicePairServiceImpl implements  DevicePairService {

    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private GcsManageFeignService gcsManageFeignService;
    @Autowired
    private RedisUtil redisUtil;

    @Value("${gridServer.url}")
    private String gridServerUrl;

    @Value("${redisKey.rPairedX}")
    private String rPairedXKey;
    @Value("${redisKey.xPairedR}")
    private String xPairedRKey;
    @Value("${redisTTL.xrPaired}")
    private long xrPairedTTL;
    @Value("${listGcsPairUseGcsManage}")
    private boolean listGcsPairUseGcsManage;

    @Override
    public List<String> listRPairT(String rid) {
        List<String> tids = new ArrayList<>();
        Map<String, PSR> prs = PtsPrs.getPrs();
        Map<String, PST> pts = PtsPrs.getPts();

        PSR psr = prs.get(rid);
        if (psr != null) {
            Set<String> targetTIds = psr.getTIds();
            for (PST pst : pts.values()) {
                if(psr.getCompanyName() != null && pst.getCompanyName() != null && pst.getCompanyName().equalsIgnoreCase(psr.getCompanyName())){
                    tids.add(pst.getId());
                    continue;
                }
                if (targetTIds.contains(pst.getId())) {
                    tids.add(pst.getId());
                }
            }
        }
        return tids;
    }

    @Override
    public List<String> listCacheRPairX(String rid) throws Exception {
        List<String> list = (List<String>)redisUtil.get(rPairedXKey + rid);
        if (list != null) {
            return list;
        }
        list = this.listRPairX(rid);
        if (list != null) {
            redisUtil.set(rPairedXKey + rid, list, xrPairedTTL);
        }
        return list;
    }

    @Override
    public List<String> listRPairX(String rid) throws Exception {
        Set<String> rids = new HashSet<>();
        rids.add(rid);
        Set<String> result = gcsManageFeignService.listRsPairedXids(rids);
        if (CollectionUtils.isEmpty(result)) {
            return new ArrayList<>();
        }
        return new ArrayList<>(result);


//        if (listGcsPairUseGcsManage) {
//            List<String> list = gcsManageFeignService.listRPairedX(rid);
//            log.info("RPC gcs-manage listRPairedX rid:{} result:{}", rid, list);
//            return list;
//        } else {
//            List<String> result = new ArrayList<>();
//            Node node = queryAllPairGrid(gridServerUrl + "/getXmlFile.action?type=r&peerid=" + rid + "");
//            if (node!=null) {
//                if ( node.getFirstChild() != null && node.getFirstChild().getChildNodes() != null ) {
//                    for (int i = 0; i < node.getFirstChild().getChildNodes().getLength(); i++) {
//                        Node inputs = node.getFirstChild().getChildNodes().item(i);
//                        NamedNodeMap attrs = inputs.getAttributes();
//                        String peerId = attrs.getNamedItem("ID").getNodeValue().toLowerCase() + attrs.getNamedItem("AppendixID").getNodeValue();
//                        if ( StringUtils.isNotBlank(peerId) ) {
//                            result.add(peerId);
//                        }
//                    }
//                }
//            }
//            return result;
//        }
    }

    @Override
    public List<String> listTPairR(String tid) {
        List<String> rids = new ArrayList<>();
        Map<String, PSR> prs = PtsPrs.getPrs();
        Map<String, PST> pts = PtsPrs.getPts();

        PST pst = pts.get(tid);
        if (pst != null) {
            Set<String> targetRIds = pst.getRIds();
            for (PSR psr : prs.values()) {
                if(pst.getCompanyName() != null && psr.getCompanyName() != null && psr.getCompanyName().equalsIgnoreCase(pst.getCompanyName())){
                    rids.add(psr.getId());
                    continue;
                }
                if (targetRIds.contains(psr.getId())) {
                    rids.add(psr.getId());
                }
            }
        }
        return rids;
    }

    @Override
    public List<String> listCacheXPairR(String xid) throws IOException {
        List<String> list = (List<String>)redisUtil.get(xPairedRKey + xid);
        if (list != null) {
            return list;
        }
        list = this.listXPairR(xid);
        if (list != null) {
            redisUtil.set(xPairedRKey + xid, list, xrPairedTTL);
        }
        return list;
    }

    @Override
    public List<String> listXPairR(String xid) throws IOException {
        if (StringUtils.isEmpty(xid)) {
            log.error("listXPairR failed xid is null");
            return null;
        }
        if (xid.length() != 32) {
            log.error("listXPairR failed xid length not 32 xid:{}", xid);
            return null;
        }
        if (listGcsPairUseGcsManage) {
            String deviceId = xid.substring(0, 16);
            String sourceId = xid.substring(16);
            List<String> list = gcsManageFeignService.listXPairedR(deviceId, sourceId);
            log.info("RPC gcs-manage listXPairedR deviceId:{} sourceId:{} result:{}", deviceId, sourceId, list);
            return list;
        } else {
            String url = gridServerUrl + "/getPairRBySourceId.action?peerid=" + xid;
            log.info("RPC GridServer GetPairXByR :url:{}", url);
            ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class);
            if (responseEntity.getStatusCodeValue() != 200) {
                log.error("RPC GridServer GetPairXByR failed:result:{}", responseEntity);
                throw new ClientException("GridServer GetPairXByR Error");
            }
            log.info("RPC GridServer GetPairXByR :result:{}", responseEntity);
            String result = responseEntity.getBody();
            List<String> rids = new ArrayList<>();
            if ( StringUtils.isNotBlank(result) && !"[]".equals(result) ) {
                JsonNode jsonTree = MyUtil.MAPPER_NON_NULL.readTree(result);
                for (JsonNode jsonNode : jsonTree) {
                    JsonNode rid = jsonNode.get("device_id");
                    if (rid != null) {
                        rids.add(rid.asText().toLowerCase());
                    }
                }
            }
            return rids;
        }
    }

    @Override
    public Set<String> listRsPairTids(Set<String> rids) {
        if (CollectionUtils.isEmpty(rids)) {
            return new HashSet<>();
        }
        Set<String> result = new HashSet<>();
        for (String rid : rids) {
            List<String> tids = this.listRPairT(rid);
            if (CollectionUtils.isEmpty(tids)) {
                continue;
            }
            result.addAll(tids);
        }
        return result;
    }

 /*   private Node queryAllPairGrid(String url) throws Exception {

        log.info("RPC GridServer GetPairXByR :url:{}", url);
        ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class);
        if (responseEntity.getStatusCodeValue() != 200) {
            log.error("RPC GridServer GetPairXByR failed:result:{}", responseEntity);
            throw new ClientException("GridServer GetPairXByR Error");
        }
        log.info("RPC GridServer GetPairXByR :result:{}", responseEntity);
        String responseText = responseEntity.getBody().replace("\n","");
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse(new ByteArrayInputStream(responseText.getBytes()));
        if (doc.getElementsByTagName("GridConfig").item(0) != null) {
            Node node = doc.getElementsByTagName("GridConfig").item(0);
            return node;
        }
        return null;
    }*/
}
